<?php
///////////////////////////////////////////////////////////////////////////////////////////////////////
//  这个文件是 JCAT PHP框架的一部，该项目和此文件 均遵循 GNU 自由软件协议
// 
//  Copyleft 2008 JeCat.cn(http://team.JeCat.cn)
//
//
//  JCAT PHP框架 的正式全名是：Jellicle Cat PHP Framework。
//  “Jellicle Cat”出自 Andrew Lloyd Webber的音乐剧《猫》（《Prologue:Jellicle Songs for Jellicle Cats》）。
//  JCAT 是一个开源项目，它像音乐剧中的猫一样自由，你可以毫无顾忌地使用JCAT PHP框架。
//  JCAT 由中国团队开发维护，是一个国际性的项目。
//  正在使用的这个版本是：0.3.1 / SVN信息：$Id: class.JCAT_Flyweight.php 1119 2008-10-25 03:55:26Z alee $
//
//
//
//  相关的链接：
//    [主页] http://jcat.JeCat.cn
//    [HTTP下载] http://jcat.JeCat.cn/download
//    [在线文档] http://jcat.JeCat.cn/document
//    [社区] http://jj.jecat.cn/forum-7-1.html
//  不很相关：
//    [MP3] http://www.google.cn/search?q=jellicle+songs+for+jellicle+cats+Andrew+Lloyd+Webber
//    [VCD/DVD] http://www.google.cn/search?q=CAT+Andrew+Lloyd+Webber+video
//
///////////////////////////////////////////////////////////////////////////////////////////////////////
/*-- Project Introduce --*/



JCAT_Package::ImportInterface('JCAT_IFlyweight',JCAT::PACKAGE_PATTERN) ;


/**
 * 享元实例 统一管理器
 *
 * @author		alee
 * @access		public
 */
class JCAT_Flyweight extends JCAT_Singleton
{


	/**
	 * 创建或返回 享元实例
	 * 
	 * @access	public
	 * @param	$sClass			string	类名
	 * @param	$Paramer...		mixed	创建享元实例的参数
	 * @static
	 * @return	
	 */
	static public function GetGlobalInstance( $sClass ) 
	{
		JCAT_ASSERT::ASSERT_ISTHESE($sClass,'string',JCAT_Language::SentenceEx('参数 $sClass 必须为 string 类型。','JCAT',null)) ;
		JCAT_ASSERT::ASSERT_(func_num_args()>1,JCAT_Language::SentenceEx('取得一个享元实例，其参数不应该小于两个','JCAT',null)) ;
		
		// 创建 新实例前 检查 是不是有效的 享元类
		if( $sMsg=JCAT_Language::SentenceEx('参数 $sClass 不是一个有效的享元类。','JCAT',null) and !self::IsFlyweightClass($sClass) )
		{
			throw new JCAT_Exception( $sMsg, JCAT_Exception::MakeExceptionCode(__CLASS__,JCAT_Exception::MakeExceptionCode(__CLASS__,1)) ) ;
		}
		
		// 享元 Key
		$arrArgs = func_get_args() ;
		array_shift($arrArgs) ;
		$sKey = call_user_func_array(array($sClass,'GetFlyweightKey'),$arrArgs) ;
			
		
		// 返回已经存在的实例
		if( isset(self::$arrInstances[$sClass][$sKey]) )
		{
			return self::$arrInstances[$sClass][$sKey] ;
		}
		
		
		
		// 工厂方法
		$Factory = isset(self::$arrInstanceFactorys[$sClass])? self::$arrInstanceFactorys[$sClass]: $sClass ;
		$sFactoryMethodName = is_array($Factory)? $Factory[1]: $Factory ;
		
		// 通过构造函数
		if( ($sFactoryMethodName=='__construct' or $sFactoryMethodName==$sClass) )
		{
			return JCAT_Global::CreateObject($sClass,$arrArgs) ;
		}

		// 通过注册的 实例工厂
		else
		{
			return self::$arrInstances[$sClass][$sKey] = call_user_func_array($Factory,$arrArgs) ;
		}
	}



	/**
	 * 是否 是一个享元类
	 * 
	 * @access	public
	 * @param	$sClass	string	类名
	 * @return	bool
	 */
	static public function IsFlyweightClass( $sClass ) 
	{
		if( !JCAT_Global::HasImplementedTo($sClass,'JCAT_IFlyweight',false) )
		{
			return false ;
		}
		
		return true ;
	}
}
/*macro_exception_code:2*/
?>